package com.zhoulu.service.borrowRecord;

import com.zhoulu.constant.Overdue;
import com.zhoulu.domain.book.BookBean;
import com.zhoulu.domain.borrowRecord.BorrowRecord;
import com.zhoulu.domain.borrowRecord.BorrowRecordSearch;
import com.zhoulu.domain.borrowRecord.BorrowRecordView;
import com.zhoulu.domain.user.UserBean;
import com.zhoulu.domain.util.LayuiResult;
import com.zhoulu.enums.RoleEnum;
import com.zhoulu.mapper.borrowRecord.BorrowRecordMapper;
import com.zhoulu.service.book.BookService;
import com.zhoulu.util.PageRequest;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;


@Service
public class BorrowRecordService {

    @Autowired
    private BorrowRecordMapper borrowRecordMapper;
    @Autowired
    private BookService bookService;

    /**
     * 查询借阅记录
     * @param borrowRecord
     * @return
     */
    public List<BorrowRecord> findBorrowRecordList(BorrowRecord borrowRecord){
        return borrowRecordMapper.findBorrowRecordList(borrowRecord);
    }

    /**
     * 新增借阅记录
     * @param borrowRecord
     */
    public void insertBorrowRecord(BorrowRecord borrowRecord){
        borrowRecordMapper.insertBorrowRecord(borrowRecord);
    }

    /**
     * 还书
     * @param id 借阅记录id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public LayuiResult returnBook(Integer id){
        if(id == null){
            return LayuiResult.error("id为空，不允许还书！");
        }
        BorrowRecord recordSearch = new BorrowRecord();
        recordSearch.setId(id);
        List<BorrowRecord> borrowRecordList = findBorrowRecordList(recordSearch);
        if(borrowRecordList == null || borrowRecordList.size() == 0){
            return LayuiResult.error(MessageFormat.format("没有查询到id为{0}的借阅记录，不允许还书！", id));
        }
        BorrowRecord borrowRecordResult = borrowRecordList.get(0);
        UserBean loginUser = (UserBean) SecurityUtils.getSubject().getPrincipal();
        if(loginUser.getId().intValue() != borrowRecordResult.getUserId().intValue()){
            return LayuiResult.error("不允许为其他人还书！");
        }
        if(borrowRecordResult.getReturnTime() != null){
            return LayuiResult.error("该书已还，无需再还！");
        }
        // 1、更新借阅记录的还书时间
        BorrowRecord borrowRecordUpdate = new BorrowRecord();
        borrowRecordUpdate.setId(id);
        borrowRecordUpdate.setReturnTime(new Date());
        updateBorrowRecord(borrowRecordUpdate);
        // 2、更新图书的库存
        BookBean bookSearch = new BookBean();
        bookSearch.setId(borrowRecordResult.getBookId());
        List<BookBean> bookList = bookService.findBookList(bookSearch);
        if(bookList == null || bookList.size() == 0){
            return LayuiResult.error(MessageFormat.format("没有查询到id为{0}的图书，不允许还书！", borrowRecordResult.getBookId()));
        }
        BookBean bookUpdate = new BookBean();
        bookUpdate.setBookNo(bookList.get(0).getBookNo());
        bookUpdate.setQty(bookList.get(0).getQty() + borrowRecordResult.getQty());
        bookService.updateBook(bookUpdate);
        return LayuiResult.success("还书成功");
    }

    /**
     * 更新借阅记录
     * @param borrowRecord
     */
    private void updateBorrowRecord(BorrowRecord borrowRecord){
        borrowRecordMapper.updateBorrowRecord(borrowRecord);
    }

    public PageInfo<BorrowRecordView> pageBorrowRecord(BorrowRecordSearch search, PageRequest pageRequest){
        PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
        List<BorrowRecordView> borrowRecordViewList = borrowRecordMapper.findBorrowRecordViewList(search);
        // 计算距离超期的剩余时间 是否超期
        Date beyondDate = null;
        for (BorrowRecordView view : borrowRecordViewList) {
            if(RoleEnum.Student.getCode().equals(view.getRoleCode())){
                view.setRoleName(RoleEnum.Student.getName());
            }else if(RoleEnum.Teacher.getCode().equals(view.getRoleCode())){
                view.setRoleName(RoleEnum.Teacher.getName());
            } else {
                view.setRoleName(RoleEnum.Admin.getName());
            }
            beyondDate = null;
            if(view.getReturnTime() != null){
                view.setRemainTime("");
            }else{
                if(RoleEnum.Student.getCode().equals(view.getRoleCode())){
                    beyondDate = getBeyondTime(view.getBorrowTime(), Overdue.studentDay);
                }else if(RoleEnum.Teacher.getCode().equals(view.getRoleCode())){
                    beyondDate = getBeyondTime(view.getBorrowTime(), Overdue.teacherDay);
                } else {
                    // 管理员没有超期时间限制
                }
                if(beyondDate != null){
                    if(beyondDate.compareTo(new Date()) == -1){
                        view.setIfBeyond(true);
                        view.setRemainTime("");
                    }else{
                        view.setIfBeyond(false);
                        view.setRemainTime(getTimeDiff(beyondDate));
                    }
                }else{
                    view.setIfBeyond(false);
                    view.setRemainTime("");
                }
            }
        }
        PageInfo<BorrowRecordView> pageInfo = new PageInfo<>(borrowRecordViewList);
        return pageInfo;
    }

    /**
     * 计算超期时间点
     * @param borrowDate 借书时间
     * @param day 最大借书天数
     * @return
     */
    private Date getBeyondTime(Date borrowDate, Integer day){
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(borrowDate);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 计算时间间隔
     * @param date
     * @return
     */
    private static String getTimeDiff(Date date) {
        StringBuilder sb = new StringBuilder();
        try {
            Date parse = date;
            Date now = new Date();
            // 这样得到的差值是微秒级别
            long diff = parse.getTime() - now.getTime();
            // 只能精确到日 无法具细到年 月 不能确定一个月具体多少天 不能确定一年具体多少天
            // 获取日
            long day = diff / (1000 * 60 * 60 * 24);
            diff = diff % (1000 * 60 * 60 * 24);
            if (day > 0) {
                sb.append(day).append("天");
            }
            // 获取时
            long hour = diff / (1000 * 60 * 60);
            diff = diff % (1000 * 60 * 60);
            if (hour > 0) {
                sb.append(hour).append("时");
            }
            // 获取分
            long min = diff / (1000 * 60);
            diff = diff % (1000 * 60);
            if (min > 0) {
                sb.append(min).append("分");
            }
            // 获取秒
            long sec = diff / 1000;
            if (sec > 0) {
                sb.append(sec).append("秒");
            }
            return sb.toString();
        } catch (Exception e) {
            return "";
        }
    }
}
